home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!sdrc!cinnet!spca6!uccba!ucunix!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!apple!sun-barr!newstop!sun!hpkronos.hpl.hp.com
- From: kk@hpkronos.hpl.hp.com (Konstantinos Konstantinides)
- Newsgroups: comp.sources.x
- Subject: v08i072: dtree, Part01/02
- Message-ID: <140746@sun.Engngun.COM>
- Date: 16 Aug 90 03:04:27 GMT
- Sender: news@sun.EnSun.COM
- Lines: 2095
- Approved: argv@sun.com
-
- Submitted-by: Konstantinos Konstantinides <kk@hpkronos.hpl.hp.com>
- Posting-number: Volume 8, Issue 72
- Archive-name: dtree/part01
-
- This version of dtree is an X extension of the program originally
- written by Dave Borman. It displays on a terminal or under X11
- (using Motif widgets) the tree structure of a Unix directory tree.
- On a color terminal, different colors can be used for files, directories,
- and symbolic links. One can select nodes of the tree, and edit them,
- view them, or print them. One can also traverse nodes not fully
- shown on the original tree.
-
- K. Konstantinides
- kk@hpkronos.hpl.hp.com
- -------------------------Beginning of submission--Part 1 of 2----------
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by Konstantinos Konstantinides <kk@hpkronos> on Tue Aug 14 15:06:50 1990
- #
- # This archive contains:
- # dtree.1 dtree.c Makefile Dtree
- # dtree-i.h Imakefile README
- #
-
- LANG=""; export LANG
- PATH=/bin:/usr/bin:$PATH; export PATH
-
- echo x - dtree.1
- cat >dtree.1 <<'@EOF'
- .TH DTREE 1L
- .SH NAME
- dtree \- display directory tree structures
- .SH SYNOPSIS
- .B dtree
- [
- .I \-aDfghHNpsStvx
- ] [
- .I \-l level
- ] [
- .I \-c linelength
- ] [
- .BR directory ...
- ]
- .SH DESCRIPTION
- .I dtree
- displays a graphic representation of the directory structure of each given
- .B directory
- and its children either on the terminal stdout or on an X11 window, using
- the Motif widgets (default). If no directories are specified, the current
- directory is used.
- By default, only directories, not regular files, are shown, and only their
- filenames are given. Various options add additional
- information to the tree.
- .SS OPTIONS
- .TP
- .I \-a
- Include files in the listing (excluding entries beginning with '.').
- .TP
- .I \-c linelength
- Make
- .I linelength
- the length of each
- column of the printout. By default, this is 14.
- Any entries longer than
- the column length are truncated accordingly, and the last character that
- fits into the column is replaced by an asterisk.
- This option only has an effect if the
- .I -v
- option is specified.
- .TP
- .I \-l level
- Search only up to the specified level. (Maximum is 10).
- .TP
- .I \-D
- List directories first. For each directory, its subdirectories
- will be listed first, and then all of its other entries.
- .TP
- .I \-f
- List files first. The reverse of
- .IR \-D .
- .TP
- .I \-S
- Long listing. Display useful information to the right of
- each entry: the name of the file's owner, its size in blocks, and its mode.
- .TP
- .I \-g
- Same as the
- .I \-S
- option, except that the group name is used instead of
- the owner name. If both the
- .I \-S
- and
- .I \-g
- options are used, both the
- owner and group will be displayed.
- .TP
- .I \-H
- Display a header at the top of the printout that gives the time and
- date that the printout was made and a summary of the type of
- information contained in the tree.
- .TP
- .I \-N
- No sort. Entries are listed in the order they are read
- from the directories.
- .TP
- .I \-p
- Include entries beginning with '.' (except '.' and '..').
- .TP
- .I \-s
- Simplify the long listing: display the user id, size in blocks, and
- octal mode of the file. This option implies the
- .I \-S
- option unless the
- .I \-g
- option is specified.
- .TP
- .I \-v
- Do not let column lengths vary; use the same
- width for each column of output. The width defaults to 14
- but can be set with the
- .I \-c
- option.
- .TP
- .I \-x
- Do not cross file systems.
- .I dtree
- will not cross over to a
- subdirectory if it is on a different file system.
- .TP
- .I \-h
- Will print a list of the options.
- .TP
- .I \-t
- Terminal mode.
- In default mode
- .I
- dtree
- will display the directory tree structure in an X11 window.
- The \-t option allows the tree to be printed on the terminal stdout.
-
- Under the X11 window mode, a button click on a tree node, makes it
- the "active" node. The name of the "active" node always appears
- at the top of the window, by the "quit" button.
- With a button click in the area where the "active" node is shown,
- a menu appears with the mode of the node, the group and user IDs,
- and \fIfile\fR or \fIdirectory\fR options .
- There are
- four \fIfile\fR options: \fIview, topview, edit\fR and \fIprint\fR.
- There are three \fIdirectory\fR options: \fIshow subtree, list files\fR,
- and \fIlist '../'\fR.
- Thus, the \-c, \-S, \-g, \-s, and \-v options are meaningful only
- when the \-t option is used.
- .TP
- .B view
- Display the whole file on a scrolled window.
- Since the program reads a file all at once,
- the wait may be significant for a very large file. However, the option
- .TP
- .B topview
- shows only the top of the file (2000 bytes).
- .TP
- .B edit
- Edit the file. \fIdtree\fR first checks and executes the command
- specified by the
- .B dtree*editor:
- resource in .Xdefaults. If that command is NULL, \fIdtree\fR
- forks an hpterm window using the editor command specified
- in the
- .B EDITOR
- environmental variable. If that variable is not specified, it uses \fIvi\fR
- .TP
- .B print
- Print the file. It prints the file on the printer destination specified
- by the
- .B dtree*lpdest:
- resource in .Xdefaults.
- If that variable is not specified it uses
- the default lp destination.
- .TP
- .B "show subtree"
- Show the directory subtree starting from the selected "active"
- directory node.
- .TP
- .B "list files"
- List all files and directories for the "active" directory node.
- This is equivalent to an "ls" command on that directory.
- .TP
- .B "list \.\.\/"
- List the directories in the parent (top) directory. Allows the user
- to traverse upwards the directory tree.
-
- Except for the \fIview\fR and \fItopview\fR options, in all other cases
- a click on the "quit" button of the "parent" will
- cause the "parent" \fIdtree\fR window to freeze until the selected command
- has been executed or the "child" window has been killed.
- Then the "parent" window will automatically die.
- Thus it is recommended to kill "children" applications before
- you try to kill the "parent".
-
- On a color terminal, one can choose different colors to distinguish
- between directories, files, and symbolic links.
- When the XmGraph widget is used, the directory tree can be seen both
- vertically and horizontally.
- To set up a simple color scheme for \fIdtree\fR, put the following entries
- in your ~/.Xdefaults file:
-
- dtree*geometry: 500x500
- .br
- dtree*quit.background: DarkSlateBlue
- .br
- dtree*dir.background: Red
- .br
- dtree*sym_link.background: Brown
- .br
- dtree*options.background: Red
-
- A set of simple resources is also specified in
- /usr/lib/X11/app-defaults/Dtree
- .SH AUTHOR
- Dave Borman, Digital Unix Engineering Group
- .br
- decvax!borman
- .br
- Originally written at St. Olaf College, Northfield, MN.
- .br
- Additions for the X11 windows display by K. Konstantinides,
- Hewlett-Packard Laboratories.
- Copyright: Hewlett-Packard, 1990.
- e-mail:kk@hpkronos.hpl.hp.com
- @EOF
-
- chmod 644 dtree.1
-
- echo x - dtree.c
- cat >dtree.c <<'@EOF'
- /*
- * DTREE - Print the tree structure of a directory
- * 4/7/83 name was changed from TREE to DTREE
- * 9/7/83 mods for 4.1c and 4.2 dirctory structure added
- *
- * Dave Borman, Digital Unix Engineering Group
- * decvax!borman
- * Originally written at St. Olaf College, Northfield MN.
- * Copyright (c) 1983 by Dave Borman
- * All rights reserved
- * This program may not be sold, but may be distributed
- * provided this header is included.
- *
- * Usage: dtree [-aDfghHlNpstvx] [-c line-length] [directory...]
- * Flags: -a) include non-directory entries in listing
- * -D) sort tree with directories at the top
- * -f) sort tree with files at the top
- * -g) same as l, but use group name instead of user name
- * -h) help
- * -H) display a header at top
- * -S) print stats with each listing
- * if both g & l flags are given, both owner and
- * group will be printed
- * -N) do not sort the tree
- * -p) include files starting with a '.' (except "." & "..")
- * -s) use shorter stats. Implies -S if -g isn't given.
- * -t) Use terminal mode (no X windows)
- * -v) variable length columns off
- * -x) do not cross mounted file systems.
- * -c length) set max column length to "length"
- * -l level) search up to the specified "level".
- */
-
- /* Modified by Ed Arnold CSU-CS (csu-cs!arnold) 3-5-84
- *
- * Allows symbolic links to both directories and individual files.
- * With a '-S' or '-aS' option, links are denoted with a 'l' in front of
- * file or directory permissions. In all other instances both links to
- * directories and files are represented just as files are. Contents of
- * linked directories are not printed due to the possibility of
- * recursively linked directories.
- *
- * Big directory name option added by:
- * Mike Vevea CSU-CS (csu-cs!vevea) 3-22-84
- *
- * Toggle sense of -v (running 4.2), and eliminate some extraneous
- * print info Mike Meyer Energy Analysts (mwm@ea) 4/17/84
- *
- * Fix the exit status to correctly indicate what happened.
- * Mike Meyer Energy Analysts (mwm@ea) 4/23/84
- *
- * Change MAX to INITIAL_ELEM to fix conflict on Suns,
- * fix incorrect default value for Clength when -v not given,
- * add -H option to print header with date and description of tree,
- * remove -b option (useless) and simplify array access,
- * use getopt to parse options, fix usage message,
- * use getwd instead of opening a pipe to pwd,
- * make error messages more informative,
- * use strncpy instead of sprintf for speed,
- * move function declarations to top of file,
- * comment out junk after #else and #endif,
- * make symbolic link configuring automatic,
- * check all error returns from malloc and realloc,
- * add System V/Xenix/Unos compatibility,
- * remove definition of rindex.
- * David MacKenzie <djm@enumd.edu> 12/20/89
- *
- * Modified to display the tree on X11 windows using the Motif
- * widgets and the Tree widget described by D.Young in his book,
- * "The X Window System, Programming and applications with Xt,
- * OSF/MOTIF EDITION", Prentice Hall, 1990.
- * Clicking on the "active" node pops-up a menu with the Mode, and Group
- * and User IDs. Clicking on "view" pops up a window with the whole
- * contents of the file. Clicking on "topview" shows the top
- * of the file only (2000 bytes).
- * On the tree, files, directories, and symbolic links can be
- * shown with different colors.
- * Changed some options so there is no conflict with X-window
- * options ( -d to -D, and -n to -N).
- * Added the -t and -h options. Changed the -l option to -S
- * Added the "-l level" option.
- * Konstantinos Konstantinides, Hewlett-Packard Laboratories
- * konstantinos_konstantinides@hplabs.hp.com 3/23/90
- *
- * Copyright: HEWLETT-PACKARD, 1990
- * Motif is a trademark of Open Software Foundation, Inc.
- * X Window System is a trademark of the Massachusetts Institute of
- * Technology
- *
- * Added support for both the Tree and XmGraph widgets
- * K. Konstantinides 4/16/90
- */
-
- /* Compile-time options:
- *
- * STATS leave undefined to remove stats, giving more core space
- * and thus the ability to tree larger tree structures on PDP 11/70s.
- *
- * NEWDIR directory structure a la Berkeley 4.1c or 4.2
- *
- * NDIR use <sys/ndir.h> instead of <sys/dir.h>
- * NEWDIR must be defined as well.
- *
- * DIRENT use Posix directory library.
- * NEWDIR must be defined as well.
- *
- * SYSV use getcwd instead of getwd, strrchr instead of rindex.
- */
- void re_orient();
- void disarm_callback();
- void activate_callback();
- void arm_callback();
- void clickB();
- void w_print();
- void button_print();
- void pop_data();
- void view();
- void quit_b();
- void quit_b_pop();
- void do_menu();
-
- static char Sccsid[]="@(#)dtree.c 2.3 2/14/84";
-
- #ifdef S_IFLNK
- static char Rcsid[] ="$Header: dtree.c,v 1.7.1.2 90/04/18 09:57:30 kk Exp $";
- #endif /* S_IFLNK */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <string.h>
- #include <stdlib.h>
-
- /* Include files for X windows */
- #include <X11/Intrinsic.h>
- #include <X11/Shell.h>
- #include <X11/StringDefs.h>
- #include <Xm/Xm.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/PushBG.h>
- #include <Xm/CascadeB.h>
- #include <Xm/RowColumn.h>
- #include <Xm/ScrolledW.h>
- #include <Xm/Separator.h>
- #include <Xm/MainW.h>
- #include <Xm/Frame.h>
- #include <Xm/Text.h>
- #ifdef TREE
- #include "Tree.h"
- #else
- #include "Graph.h"
- #include "Arc.h"
- #endif
-
- /* Original Defs */
- #ifdef STATS
- # include <pwd.h>
- # include <grp.h>
- #endif /* STATS */
-
- #ifdef NEWDIR
- # if DIRENT
- # include <dirent.h>
- # define direct dirent
- # else
- # if NDIR
- # include <sys/ndir.h>
- # else
- # include <sys/dir.h>
- # endif
- # endif /* DIRENT */
- #else
- # include <sys/dir.h>
- #endif /* NEWDIR */
-
- /* default column length when -v is given */
- #ifdef unos
- #define DEFCOLWID 30
- #else
- #define DEFCOLWID 14
- #endif
-
- #include <sys/param.h> /* for MAXPATHLEN */
- #ifndef MAXPATHLEN
- # ifdef LPNMAX /* Xenix from stdio.h */
- # define MAXPATHLEN (LPNMAX - 1)
- # else
- # include <limits.h> /* try somewhere else */
- # define MAXPATHLEN PATH_MAX
- # endif
- #endif
-
- #ifndef MAXNAMLEN /* defined with NEWDIR routines */
- # ifdef LFNMAX /* Xenix again */
- # define MAXNAMLEN (LFNMAX - 1)
- # else
- # define MAXNAMLEN DEFCOLWID
- # endif
- #endif
-
- #define DEPTH 10 /* maximum depth that dtree will go */
- #define INITIAL_ELEM 100 /* initial # of elements for list of files */
-
- #define FFIRST 2 /* sort files first */
- #define DFIRST 1 /* sort directories first */
- #define FAIL -1 /* failure return status of sys calls */
- #define GREATER 1 /* return value of strcmp if arg1 > arg2 */
- #define LESSTHAN -1 /* return value of strcmp if arg1 < arg2 */
- #define SAME 0 /* return value of strcmp if arg1 == arg2 */
-
- #ifdef STATS
- char *getmode();
- char *guid();
- char *ggid();
- struct passwd *getpwuid();
- struct group *getgrgid();
- #endif /* STATS */
-
- #ifdef SYSV
- #define rindex strrchr
- #endif /* SYSV */
-
- char *getwd();
- char *rindex();
- /*
- int qsort();
- char *malloc();
- char *realloc();
- */
- long time();
-
- int compar(); /* comparison routine for qsort */
- char *xmalloc();
- char *xrealloc();
-
- #ifdef SYSV
- #define getwd(buf) getcwd((buf), MAXPATHLEN + 1)
- #endif /* SYSV */
-
- int Index = 0; /* current element of list[] */
- int CLength = 0; /* max length of a column */
- int All = 0; /* all != 0; list non-directory entries */
- int File_dir = 0; /* flag for how to sort */
- int Sort = 1; /* flag to cause sorting of entries */
- int Point = 1; /* skip point files if set */
- int Header = 0; /* print verbose header */
- int Maxes[DEPTH]; /* array keeps track of max length in columns */
- int Level = 0; /* counter for how deep we are */
- int Device; /* device that we are starting tree on */
- int Xdev = 1; /* set to allow crossing of devices */
- int Varspaces = 1; /* set to allow compaction of column width */
- #ifdef STATS
- int Gflag = 0; /* set for group stats instead of owner */
- int Longflg = 0; /* set for long listing */
- int Compact = 0; /* set for shortened long listing */
- #endif /* STATS */
- #undef Status
- struct stat Status;
- #ifdef S_IFLNK
- struct stat Lstat; /* stat of link, if there is one */
- #endif /* S_IFLNK */
-
- struct entry {
- int next; /* index to next element in list */
- /* could be a ptr, but realloc() */
- /* might screw us then */
- #ifdef STATS
- off_t e_size; /* size in blocks */
- unsigned short e_mode; /* file mode */
- short e_uid; /* uid of owner */
- short e_gid; /* gid of owner */
- #endif /* STATS */
- unsigned short dir : 1; /* entry is a directory */
- unsigned short last : 1; /* last entry in the dir. */
- unsigned short dev : 1; /* set if same device as top */
- unsigned short end : 13; /* index of last subdir entry*/
- char e_name[MAXNAMLEN + 1]; /* name from directory entry */
- char path_name[MAXPATHLEN + 1]; /* path name */
- } *List, *SaveList;
-
- unsigned Size; /* how big of space we've malloced */
-
- char *Spaces; /* used for output */
- char Buf1[BUFSIZ]; /* buffers for stdio stuff. We don't want */
- #ifndef NEWDIR
- char Buf2[BUFSIZ]; /* anyone calling malloc, because then */
- /* realloc() will have to move the whole list */
- #endif
- #define FS(str) (void) fprintf(stderr,str)
-
- help()
- {
- fprintf(stderr,
- #ifdef STATS
- "Usage: dtree [-aDfghHlNpstvx] [-c linelength] [directory ... ]\n"
- #else /* STATS */
- "Usage: dtree [-aDfhHNptvx] [-c linelength] [directory ... ]\n"
- #endif /* STATS */
- );
- FS(" options -a) include non-directory entries in listing\n");
- FS(" -D) sort tree with directories at the top\n");
- FS(" -f) sort tree with files at the top\n");
- FS(" -h) help - prints this message\n");
- FS(" -H) display a header at top\n");
- FS(" -x) do not cross mounted file systems.\n");
- FS(" -p) include files starting with a . (except . and ..)\n");
- FS(" -N) do not sort the tree\n");
- FS(" -t) Use terminal mode, don't display on an X window\n\n");
- FS(" -l level) Search only up to the specified level \n\n");
- FS(" Valid only if -t is used. Under default mode, a click on a \n");
- FS(" node pops up a menu with mode, user and group ids.\n\n");
- FS(" -S) print stats with each listing\n");
- FS(" if both g & l flags are given, both owner and\n");
- FS(" group will be printed\n");
- FS(" -g) same as l, but use group name instead of user name \n");
- FS(" -s) use shorter stats. Implies -S if -g isn't given.\n");
- FS(" -v) variable length columns \n");
- FS(" -c length) set max column length to -length-\n");
- FS(" X-Window version 1.1 4/16/90 \n");
- }
- int newlevel = DEPTH;
- Widget boxes[11], options;
- Widget file_menu, dir_menu;
- struct entry *file_pointer;
- main(argc, argv)
- char **argv;
- int argc;
- {
- extern int optind;
- extern char *optarg;
- register int i;
- char top[MAXPATHLEN + 1]; /* array for treetop name */
- char home[MAXPATHLEN + 1]; /* starting dir for multiple trees */
- char *ptr;
-
- Widget toplevel;
- Widget sw, tree, q_button, w_button;
- Widget menu_bar, frame, main_w, title;
- Arg wargs[10];
- int flagX=1; /* use X windows as default */
- Widget quit_menu, exit_b, reorient;
- int really_quit, n;
-
- setbuf(stdout, Buf1);
-
- while ((i = getopt (argc, argv,
- #ifdef STATS
- "haDfgHl:NpsSvxtc:"
- #else
- "haDfHl:Npvxtc:"
- #endif /* STATS */
- )) != EOF) {
- switch (i) {
- case 'a':
- All = 1;
- break;
- case 'c':
- CLength = atoi(optarg);
- if (CLength > MAXNAMLEN)
- CLength = MAXNAMLEN;
- else if (CLength < 1)
- CLength = DEFCOLWID;
- break;
- case 'l':
- newlevel = atoi(optarg);
- if(newlevel > DEPTH) {
- newlevel = DEPTH;
- }
- break;
- case 'D':
- File_dir = DFIRST;
- break;
- case 'f':
- File_dir = FFIRST;
- break;
- case 'H':
- Header = 1;
- break;
- case 'N':
- Sort = 0;
- break;
- case 'p':
- Point = 0;
- break;
- case 'v':
- Varspaces = 0;
- break;
- case 'x':
- Xdev = 0;
- break;
- case 't':
- flagX = 0;
- break;
-
- case 'h':
- help();
- exit(0);
- #ifdef STATS
- case 'g':
- Gflag = 1;
- break;
- case 'S':
- Longflg = 1;
- break;
- case 's':
- Compact = 1;
- break;
- #endif /* STATS */
- default:
- help();
- exit(FAIL);
- }
- }
- #ifdef STATS
- if (Compact && !Gflag)
- Longflg = 1;
- #endif /* STATS */
- if (CLength == 0)
- CLength = Varspaces ? MAXNAMLEN : DEFCOLWID;
-
- /* Establish where we are (our home base...) */
- if (getwd(home) == 0) {
- fprintf(stderr,
- "dtree: Cannot get initial directory: %s\n", home);
- exit(1);
- }
-
- Spaces = xmalloc(MAXNAMLEN+2);
- for(i = 0; i <= MAXNAMLEN; i++)
- Spaces[i] = ' ';
- Spaces[i] = '\0';
-
- /* Get initial Storage space */
- Size = sizeof(struct entry) * INITIAL_ELEM;
- SaveList = (struct entry *)xmalloc(Size);
-
- /* adjust for no specified directory */
- if (optind == argc )
- if(optind > 1) argv[--optind] = ".";
- else { argv[1] = ".", optind = 1; argc = 2;}
-
- if (Header)
- print_date();
-
- /* walk down the rest of the args, treeing them one at at time */
- for (; optind < argc; optind++) {
- if (chdir(home) == -1) {
- fprintf(stderr, "dtree: Cannot change to initial directory ");
- perror(home);
- exit(1);
- }
- strncpy (top, argv[optind], MAXPATHLEN);
-
- if (chdir(top) == FAIL) {
- fprintf(stderr, "dtree: Cannot change to top directory ");
- perror(top);
- continue;
- } else if (getwd(top) == 0) {
- fprintf(stderr,"dtree: Cannot get current directory: %s\n", top);
- continue;
- }
-
- List = SaveList; Index = 0;
- getwd(List[0].path_name);
- ptr = rindex(top, '/');
-
- if (!ptr || *++ptr == '\0')
- strncpy(List[Index].e_name, top, MAXNAMLEN);
- else
- strncpy(List[Index].e_name, ptr, MAXNAMLEN);
-
- if(stat(top, &Status) == FAIL) {
- fprintf(stderr, "dtree: Cannot stat directory ");
- perror(top);
- continue;
- }
- Device = Status.st_dev;
- List[0].dir = 1;
- List[0].last = 1;
- List[0].next = 1;
- #ifdef STATS
- List[0].e_mode = Status.st_mode;
- List[0].e_uid = Status.st_uid;
- List[0].e_gid = Status.st_gid;
- List[0].e_size = Status.st_size;
- #endif /* STATS */
- Index = 1;
- for (i = 1; i < DEPTH; i++)
- Maxes[i] = 0;
- Maxes[0] = stln(List[0].e_name);
- Level = 1;
-
- /* Don't waste time if there is no display */
- if(flagX == 1)
- toplevel = XtInitialize(argv[0], "Dtree", NULL, 0, &argc, argv);
-
- fprintf(stderr,"Started searchin...Please wait \n");
- /* search the tree */
- List[0].end = t_search(top, &List[0]);
-
- if (Index == 1) /* empty tree */
- List[0].next = 0;
-
- if (Header) {
- if (All)
- printf("\nDirectory structure and contents of %s\n", top);
- else
- printf("\nDirectory structure of %s\n", top);
- if (Point)
- printf("(excluding entries that begin with '.')\n");
- }
-
- if(flagX == 0) pt_tree();
- else {
-
- /* Create a MainWindow, with a MenuBar and a Frame window
- Put on the Frame, a ScrolledWindow and the Tree window
- The MenuBar has a quit button and the directory Name
- */
- fprintf(stderr,"Opening display now...Please wait\n");
-
- /* main window */
- main_w = XmCreateMainWindow(toplevel,"mainw",NULL,0);
- XtManageChild(main_w);
-
- /* menu bar */
- menu_bar = XmCreateMenuBar(main_w,"menu",NULL,0);
- XtManageChild(menu_bar);
-
- /* frame */
- XtSetArg(wargs[0], XmNshadowType, XmSHADOW_OUT);
- frame = XmCreateFrame(main_w,"frame",wargs,1);
- XtManageChild(frame);
-
- /* quit button */
-
- quit_menu = XmCreatePulldownMenu(menu_bar,
- "quit_menu",NULL,0);
- XtSetArg(wargs[0], XmNsubMenuId,quit_menu);
- q_button = XmCreateCascadeButton(menu_bar,
- "quit",wargs,1);
- XtManageChild(q_button);
-
- w_button =XtCreateManagedWidget("warning",
- xmLabelWidgetClass,quit_menu, NULL,0);
- w_print(w_button,"Don't exit unless all children are dead\n");
- exit_b = XtCreateManagedWidget("Exit",
- xmPushButtonWidgetClass, quit_menu, NULL, 0);
- XtAddCallback(exit_b, XmNarmCallback,
- arm_callback, &really_quit);
- XtAddCallback(exit_b, XmNdisarmCallback,
- disarm_callback, &really_quit);
- XtAddCallback(exit_b, XmNactivateCallback,
- activate_callback, &really_quit);
-
- #ifndef TREE
- /* Reorient button */
- reorient = XmCreateCascadeButton(menu_bar,"ReOrient",
- NULL,0);
- XtManageChild(reorient);
- #endif
- /* Create the options pull-down menu */
- file_pointer = &List[0];
- show_menu(menu_bar,file_pointer);
-
- /* title (path) widget */
-
- title = XtCreateManagedWidget("title",
- xmCascadeButtonWidgetClass, menu_bar, NULL,0);
- XtSetArg(wargs[0],XmNmenuHelpWidget, title);
- XtSetValues(menu_bar, wargs, 1);
- w_print(title,top);
-
- XtSetArg(wargs[0], XmNscrollingPolicy, XmAUTOMATIC);
- sw = XtCreateManagedWidget("swindow",
- xmScrolledWindowWidgetClass, frame, wargs, 1);
- /* Tree widget */
- #ifdef TREE
- tree = XtCreateManagedWidget("tree",XstreeWidgetClass,
- sw, NULL,0);
- #else
- n=0;
- XtSetArg(wargs[n],XmNautoLayoutMode, TRUE); n++;
- XtSetArg(wargs[n],XmNsiblingSpacing, 5); n++;
- XtSetArg(wargs[n],XmNarcDrawMode,XmPOSITION_FIXED);n++;
- tree = XmCreateGraph(sw,"tree", wargs,n);
- /* XmAddTabGroup(tree); */
- XtManageChild(tree);
-
- XtAddCallback(reorient, XmNactivateCallback,
- re_orient, tree);
- #endif
- XmMainWindowSetAreas(main_w, menu_bar, NULL,
- NULL, NULL, frame);
- show_dtree(tree);
- clickB(options,file_pointer,NULL);
- XtRealizeWidget(toplevel);
- XtMainLoop();
- }
-
- }
- exit(0) ;
- }
-
-
- t_search(dir, addrs)
- char *dir;
- struct entry *addrs;
- {
- int bsort; /* index to begin sort */
- int stmp; /* save temporary index value */
- struct entry *sstep; /* saved step in list */
- int nitems; /* # of items in this directory */
- #ifdef NEWDIR
- DIR *dirp; /* pointer to directory */
- #else
- FILE *dirp;
- #endif
- char sub[MAXNAMLEN+1]; /* used for subdirectory names */
- int i;
- #ifdef NEWDIR
- struct direct *dp;
- #else
- struct direct dirent;
- struct direct *dp = &dirent;
- #endif /* NEWDIR */
- int n_subs = 0;
- int tmp = 0;
-
- #ifdef NEWDIR
- dirp = opendir(".");
- #else
- dirp = fopen(".", "r");
- #endif /* NEWDIR */
- if (dirp == NULL) {
- fprintf(stderr, "dtree: Cannot open directory ");
- perror(dir);
- return(0);
- }
- #ifndef NEWDIR
- setbuf(dirp, Buf2);
- #endif /* NEWDIR */
-
- bsort = Index;
- sstep = &List[bsort]; /* initialize sstep for for loop later on */
- nitems = Index;
- /* get the entries of the directory that we are interested in */
- #ifndef NEWDIR
- while (fread((char *)(dp), sizeof(struct direct), 1, dirp) == 1) {
- #else
- while ((dp = readdir(dirp)) != NULL) {
- #endif /* NEWDIR */
-
- if (dp->d_ino
- #ifdef unos
- == -1
- #else
- == 0
- #endif /* unos */
- || (strcmp(dp->d_name, ".") == SAME)
- || (strcmp(dp->d_name, "..") == SAME)
- || (Point && dp->d_name[0] == '.'))
- continue;
-
- strncpy(sub, dp->d_name, MAXNAMLEN);
- #ifdef S_IFLNK
- if (lstat(sub,&Lstat) == FAIL) {
- fprintf(stderr, "dtree: In directory %s, cannot lstat entry ", dir);
- perror(sub);
- continue;
- }
- #endif /* S_IFLNK */
- if (stat(sub, &Status) == FAIL) {
- fprintf(stderr, "dtree: In directory %s, cannot stat entry ", dir);
- perror(sub);
- continue;
- }
- #ifdef S_IFLNK
- if (((Lstat.st_mode & S_IFMT) == S_IFLNK) &&
- ((Status.st_mode & S_IFMT) == S_IFDIR))
- List[Index].dir = 0;
- else if ((((Lstat.st_mode & S_IFMT) == S_IFLNK) &&
- ((Status.st_mode & S_IFMT) != S_IFDIR)) && (All))
- List[Index].dir = 0;
- #endif /* S_IFLNK */
- else if ((Status.st_mode & S_IFMT) == S_IFDIR)
- List[Index].dir = 1;
- else if (All)
- List[Index].dir = 0;
- else
- continue;
- strncpy(List[Index].e_name, dp->d_name, MAXNAMLEN);
- getwd(List[Index].path_name);
- List[Index].last = 0;
- List[Index].end = 0;
- #ifdef S_IFLNK
- if ((Lstat.st_mode & S_IFMT) == S_IFLNK) {
- List[Index].dev = (Device == Lstat.st_dev);
- List[Index].e_mode = Lstat.st_mode;
- List[Index].e_uid = Lstat.st_uid;
- List[Index].e_gid = Lstat.st_gid;
- List[Index].e_size = Lstat.st_size;
- }
- else {
- #endif /* S_IFLNK */
- List[Index].dev = (Device == Status.st_dev);
- #ifdef STATS
- List[Index].e_mode = Status.st_mode;
- List[Index].e_uid = Status.st_uid;
- List[Index].e_gid = Status.st_gid;
- List[Index].e_size = Status.st_size;
- #endif /* STATS */
- #ifdef S_IFLNK
- }
- #endif /* S_IFLNK */
- if (stln(List[Index].e_name) > Maxes[Level])
- Maxes[Level] = stln(List[Index].e_name);
- ++Index;
- if (Index*sizeof(struct entry) >= Size) {
- Size += 20*sizeof(struct entry);
- List = (struct entry *)xrealloc((char *)List, Size);
- }
- }
- #ifdef NEWDIR
- closedir(dirp);
- #else
- fclose(dirp);
- #endif /* NEWDIR */
-
- nitems = Index - nitems; /* nitems now contains the # of */
- /* items in this dir, rather than */
- /* # total items before this dir */
-
- if (Sort)
- qsort(&List[bsort], nitems, sizeof(struct entry), compar);
-
- List[Index-1].last = 1; /* mark last item for this dir */
- n_subs = nitems;
- stmp = Index;
-
- /* now walk through, and recurse on directory entries */
- /* sstep was initialized above */
-
- for (i = 0; i < nitems; sstep = &List[stmp - nitems+(++i)]) {
- if (sstep->dir && (Level < newlevel) && (Xdev || sstep->dev)) {
- sstep->next = Index;
- strncpy(sub, sstep->e_name, MAXNAMLEN);
- tmp = n_subs;
- Level++;
- if (chdir(sub) == FAIL) {
- fprintf(stderr,
- "dtree: Cannot change to directory %s/", dir);
- perror(sub);
- } else {
- n_subs += t_search(sub, sstep);
- if (chdir("..") == FAIL) {
- fprintf(stderr,
- "dtree: %s/%s lacks '..' entry\n",dir, sub);
- exit(1);
- }
- }
- --Level;
- if (n_subs - tmp <= 0)
- sstep->next = 0;
- else
- --n_subs;
- }
- else
- sstep->next = 0;
- }
- addrs->end = (unsigned)n_subs;
- return(n_subs);
- }
-
- /*
- * comparison routine for qsort
- */
-
- compar(a, b)
- struct entry *a, *b;
- {
- if (!File_dir) /* straight alphabetical */
- return(strncmp(a->e_name, b->e_name, MAXNAMLEN));
-
- /* sort alphabetically if both dirs or both not dirs */
-
- if ((a->dir && b->dir) || (!a->dir && !b->dir))
- return(strncmp(a->e_name, b->e_name, MAXNAMLEN));
-
- if (File_dir == FFIRST) { /* sort by files first */
- if (a->dir)
- return(GREATER);
- else
- return(LESSTHAN);
- }
-
- if (a->dir) /* sort by dir first */
- return(LESSTHAN);
- else
- return(GREATER);
- }
-
-
- pt_tree()
- {
- register int i,j;
- struct entry *l;
- struct entry *hdr[DEPTH];
- int posit[DEPTH]; /* array of positions to print dirs */
- int con[DEPTH]; /* flags for connecting up tree */
- char flag = 0; /* flag to leave blank line after dir */
- struct entry *stack[DEPTH]; /* save positions for changing levels */
- int top = 0; /* index to top of stack */
- int count = 1; /* count of line of output */
-
- Level = 0; /* initialize Level */
-
- /* this loop appends each entry with dashes or spaces, for */
- /* directories or files respectively */
-
- for (i = 0; i < Index; i++) {
- for (j = 0; j < MAXNAMLEN; j++) {
- if (!List[i].e_name[j])
- break;
- }
- if (List[i].dir) {
- for (; j < MAXNAMLEN; j++)
- List[i].e_name[j] = '-';
- } else {
- for (; j < MAXNAMLEN; j++)
- List[i].e_name[j] = ' ';
- }
- }
-
- /* adjust the Maxes array according to the flags */
-
- for (i = 0; i < DEPTH; i++) {
- if (Varspaces) {
- if (Maxes[i] > CLength )
- Maxes[i] = CLength;
- } else
- Maxes[i] = CLength;
- }
-
- /* clear the connective and position flags */
-
- for (i = 0; i < DEPTH; i++)
- con[i] = posit[i] = 0;
-
- /* this is the main loop to print the tree structure. */
- l = &List[0];
- j = 0;
- for (;;) {
- /* directory entry, save it for later printing */
- if (l->dir != 0 && l->next != 0) {
- hdr[Level] = l;
- posit[Level] = count + (l->end + 1)/2 - 1;
- flag = 1;
- stack[top++] = l;
- l = &List[l->next];
- ++Level;
- continue;
- }
-
- #ifdef STATS
- do_it_again:
- #endif /* STATS */
- /* print columns up to our entry */
- for (j = 0; j < (flag ? Level-1 : Level); j++) {
- if (!flag && posit[j] && posit[j] <= count) {
- /* time to print it */
- if (hdr[j]->e_name[CLength-1] != '-')
- hdr[j]->e_name[CLength-1] = '*';
- printf("|-%.*s",Maxes[j],hdr[j]->e_name);
- posit[j] = 0;
- if (hdr[j]->last != 0)
- con[j] = 0;
- else
- con[j] = 1;
- #ifdef STATS
- if (Gflag || Longflg) {
- if ((i = j+1) <= Level)
- printf("| %.*s", Maxes[i], Spaces);
- for (i++; i <= Level; i++) {
- printf("%c %.*s",
- (con[i] ? '|' : ' '),
- Maxes[i], Spaces);
- }
- if (!Compact) {
- printf("%s ", getmode(hdr[j]->e_mode));
- if (Longflg)
- printf("%8.8s ",guid(hdr[j]->e_uid));
- if (Gflag)
- printf("%8.8s ",ggid(hdr[j]->e_gid));
- printf("%7ld\n",
- (hdr[j]->e_size+511L)/512L);
- } else {
- printf(" %04o ",hdr[j]->e_mode & 07777);
- if (Longflg)
- printf("%5u ", hdr[j]->e_uid);
- if (Gflag)
- printf("%5u ", hdr[j]->e_gid);
- printf("%7ld\n",
- (hdr[j]->e_size+511L)/512L);
- }
- goto do_it_again;
- }
- #endif /* STATS */
- } else
- printf("%c %.*s", (con[j] ? '|' : ' '),
- Maxes[j], Spaces);
- }
- if (flag) { /* start of directory, so leave a blank line */
- printf(con[j] ? "|\n" : "\n");
- flag = 0;
- continue;
- } else {
- /* normal file name, print it out */
- if (l->e_name[CLength-1] != '-' &&
- l->e_name[CLength-1] != ' ')
- l->e_name[CLength-1] = '*';
- printf("|-%.*s",Maxes[Level],l->e_name);
- if (l->last) {
- con[j] = 0;
- } else {
- con[j] = 1;
- }
- #ifdef STATS
- if (Gflag || Longflg) {
- if (Compact) {
- printf(" %04o ", l->e_mode & 07777);
- if (Longflg)
- printf("%5u ", l->e_uid);
- if (Gflag)
- printf("%5u ", l->e_gid);
- printf("%7ld",
- (l->e_size+511L)/512L);
- } else {
- printf("%s ", getmode(l->e_mode));
- if (Longflg)
- printf("%8.8s ",guid(l->e_uid));
- if (Gflag)
- printf("%8.8s ",ggid(l->e_gid));
- printf("%7ld",
- (l->e_size+511L)/512L);
- }
- }
- #endif /* STATS */
- }
- printf("\n");
-
- if (l->last) {
- /* walk back up */
- while (l->last) {
- --Level;
- if (--top <= 0)
- return;
- l = stack[top];
- }
- }
- l = &l[1];
- ++count;
- }
- }
-
- #ifdef STATS
-
- char *
- guid(uid)
- short uid;
- {
- static char tb[10];
- struct passwd *pswd;
-
- pswd = getpwuid(uid);
- if (pswd == NULL)
- sprintf(tb,"%u", uid);
- else
- sprintf(tb, "%8s", pswd->pw_name);
- return(tb);
- }
-
- char *
- ggid(gid)
- short gid;
- {
- static char tb[10];
- struct group *grp;
-
- grp = getgrgid(gid);
- if (grp == NULL)
- sprintf(tb,"%u", gid);
- else
- sprintf(tb, "%8s", grp->gr_name);
- return(tb);
- }
-
- /* take the mode and make it into a nice character string */
-
- char *
- getmode(p_mode)
- unsigned short p_mode;
- {
- static char a_mode[16];
- register int i = 0, j = 0;
-
- a_mode[j++] = ' ';
-
- switch (p_mode & S_IFMT) {
- #ifdef S_IFLNK
- case S_IFLNK:
- a_mode[j++] = 'l';
- break;
- #endif /* S_IFLNK */
- case S_IFDIR:
- a_mode[j++] = 'd';
- break;
- #ifdef S_IFMPC /* defined in stat.h if you have MPX files */
- case S_IFMPC:
- a_mode[j-1] = 'm';
- /* FALL THROUGH */
- #endif /* S_IFMPC */
- case S_IFCHR:
- a_mode[j++] = 'c';
- break;
- #ifdef S_IFMPB /* defined in stat.h if you have MPX files */
- case S_IFMPB:
- a_mode[j-1] = 'm';
- /* FALL THROUGH */
- #endif /* S_IFMPB */
- case S_IFBLK:
- a_mode[j++] = 'b';
- break;
- case S_IFREG:
- default:
- a_mode[j++] = (p_mode & S_ISVTX) ? 't' : ' ';
- break;
- }
- a_mode[j++] = ' ';
- for( i = 0;i<3;i++ ) {
- a_mode[j++] = (p_mode<<(3*i) & S_IREAD) ? 'r' : '-';
- a_mode[j++] = (p_mode<<(3*i) & S_IWRITE) ? 'w' : '-';
- a_mode[j++] = (i<2 && (p_mode<<i & S_ISUID)) ? 's' :
- ((p_mode<<(3*i) & S_IEXEC ) ? 'x' : '-');
- a_mode[j++] = ' ';
- }
- a_mode[j] = '\0';
- return(a_mode);
- }
- #endif
-
- /* like strlen, but returns length up to MAXNAMLEN-1 */
- stln(st)
- register char *st;
- {
- register int t;
-
- for (t=0; t<MAXNAMLEN-1; ++t)
- if (!st[t])
- return (++t);
- return (++t);
- }
-
- print_date()
- {
- long now;
-
- time(&now);
- printf ("%s", ctime(&now));
- }
-
- void
- memory_out()
- {
- fprintf(stderr, "dtree: Virtual memory exhausted\n");
- exit(1);
- }
-
- /* Allocate `size' bytes of memory dynamically, with error checking. */
-
- char *
- xmalloc (size)
- unsigned size;
- {
- char *ptr;
-
- ptr = malloc (size);
- if (ptr == 0 && size != 0)
- memory_out ();
- return ptr;
- }
-
- /* Change the size of an allocated block of memory `ptr' to `size' bytes,
- with error checking.
- If `ptr' is NULL, run xmalloc.
- If `size' is 0, run free and return NULL. */
-
- char *
- xrealloc (ptr, size)
- char *ptr;
- unsigned size;
- {
- if (ptr == 0)
- return xmalloc (size);
- if (size == 0) {
- free (ptr);
- return 0;
- }
- ptr = realloc (ptr, size);
- if (ptr == 0 && size != 0)
- memory_out ();
- return ptr;
- }
- /*-------------------------New functions for X windows -----------------*/
-
- /* Main program to display the tree in an X window */
-
- show_dtree(parent)
- Widget parent;
-
- {
- Arg wargs[4];
- struct entry *stack[DEPTH], *branch;
- int n, top=0, *dir_index;
- int dir_node=0, dir_count=0, i;
- Widget parent_node=NULL, *Dir, arc;
- XmString label_s = NULL;
-
- /* Find the number of directories */
- for(i=0; i < Index; i++)
- if(List[i].dir == 1) dir_count++;
-
- if((Dir = (Widget *) malloc( dir_count * sizeof(Widget))) == NULL){
- fprintf(stderr,"malloc failure\n");
- exit(1);
- }
- if((dir_index = (int *) malloc(dir_count * sizeof(int))) == NULL) {
- fprintf(stderr,"malloc failure\n");
- exit(1) ;
- }
-
- branch = &List[0];
-
- if(dir_count == 1 && branch->next == 0) {
- if(All == 0) {
- fprintf(stderr,"No subdirectories under directory %s\n",
- branch->e_name);
- fprintf(stderr,"You may want to try the -ap option\n");
- }
- else fprintf(stderr,"No files under directory %s\n",
- branch->e_name);
- exit(0);
- }
-
- /* Distinguish between directories and files */
-
- for(;;) {
- if(branch->dir != 0 && branch->next != 0) {
- dir_index[top] = dir_node;
- stack[top++] = branch;
- n=0;
- #ifdef TREE
- XtSetArg(wargs[n], XtNsuperNode,parent_node); n++;
- #endif
- label_s = XmStringCreateLtoR(branch->e_name,
- XmSTRING_DEFAULT_CHARSET);
- XtSetArg(wargs[n], XmNlabelString,label_s); n++;
- Dir[dir_node] = XmCreatePushButton(parent,"dir",
- wargs,n);
- XtManageChild(Dir[dir_node]);
- XtAddCallback(Dir[dir_node],XmNactivateCallback,
- clickB, branch);
-
- #ifndef TREE
- /* create the arc */
- if(parent_node) {
- n=0;
- XtSetArg(wargs[n], XmNarcDirection, XmDIRECTED); n++;
- XtSetArg(wargs[n], XmNto, Dir[dir_node]); n++;
- XtSetArg(wargs[n], XmNfrom, parent_node); n++;
- arc = XmCreateArc(parent, branch->e_name,wargs,n);
- XtManageChild(arc);
- }
- #endif
-
- branch = &List[branch->next];
- parent_node = Dir[dir_node++];
- continue;
- }
- create_file_node(parent,branch,parent_node);
- if(branch->last) {
- while(branch->last) {
- if(--top <= 0 ) {
- free(Dir);
- free(dir_index);
- return;
- }
- branch = stack[top];
- parent_node = Dir[dir_index[top-1]];
- }
- }
- branch = &branch[1];
- }
- }
- /* Function that creates a widget for a node. Three types are available,
- dir, for directories , file, for files, and sym_link for
- symbolic links
- */
- create_file_node(pparent,bbranch,nnode)
- Widget pparent, nnode;
- struct entry *bbranch;
- {
- Widget w, arc;
- Arg wargs[4];
- int n;
- char *win_type;
- XmString label_s = NULL;
- int Gflag=1; /* this is a gadget */
-
-
- n=0;
- label_s = XmStringCreateLtoR(bbranch->e_name,
- XmSTRING_DEFAULT_CHARSET);
- XtSetArg(wargs[n], XmNlabelString,label_s); n++;
-
- /* Check the type of the node */
- if(bbranch->dir == 1) {
- win_type = "dir";
- Gflag = 0;
- }
- #ifdef STATS
- else if(strncmp(" l",getmode(bbranch->e_mode),2) == 0)
- {win_type = "sym_link"; Gflag = 0;}
- #endif /* STATS */
- else win_type = "file";
- #ifdef TREE
- XtSetArg(wargs[n], XtNsuperNode, nnode); n++;
- w = XmCreatePushButton(pparent, win_type, wargs, n);
- #else
- if(Gflag == 0)
- w = XmCreatePushButton(pparent, win_type, wargs, n);
- else
- w = XmCreatePushButtonGadget(pparent, win_type, wargs, n);
- #endif
- XtManageChild(w);
- XtAddCallback(w,XmNactivateCallback,clickB,bbranch);
-
- #ifndef TREE
- /* create the arcs */
- n=0;
- XtSetArg(wargs[n], XmNarcDirection, XmDIRECTED); n++;
- XtSetArg(wargs[n], XmNto, w); n++;
- XtSetArg(wargs[n], XmNfrom, nnode); n++;
- arc = XmCreateArc(pparent, bbranch->e_name,wargs,n);
- XtManageChild(arc);
- #endif
- }
- /* Function that creates the pull-down menu when someone clicks on the
- active node of the tree.
- */
-
- show_menu(pparent, bbranch)
- Widget pparent;
- struct entry *bbranch;
- {
- Widget menu ;
- Widget submenu_dir, submenu_file;
- int i;
- char *mode_name;
- Arg wargs[4];
-
- menu = XmCreatePulldownMenu(pparent,"menu",NULL, 0);
-
- XtSetArg(wargs[0], XmNsubMenuId,menu);
- options = XtCreateManagedWidget("options",xmCascadeButtonWidgetClass,
- pparent, wargs, 1);
- w_print(options, bbranch->e_name);
- /*
- boxes[0] = XtCreateManagedWidget("title",xmLabelWidgetClass,
- menu, NULL,0);
- XtCreateManagedWidget("separator",xmSeparatorWidgetClass,
- menu, NULL,0);
- */
- #ifdef STATS
- for(i = 1; i < 4 ; i++)
- boxes[i] = XtCreateManagedWidget("id",xmLabelWidgetClass,
- menu, NULL,0);
- button_print(bbranch); /* print the labels on the menu */
-
- XtCreateManagedWidget("separator2",xmSeparatorWidgetClass,
- menu, NULL,0);
- /* Create sub-menus */
-
- #endif /*STATS */
-
- file_menu = XtCreateManagedWidget("File Options",
- xmCascadeButtonWidgetClass, menu, NULL,0);
- dir_menu = XtCreateManagedWidget("Directory Options",
- xmCascadeButtonWidgetClass, menu, NULL,0);
-
- /* Create cascading sub-menus */
-
- /* If it is a file */
- submenu_file = XmCreatePulldownMenu(menu, "filesubmenu", NULL, 0);
- XtSetArg(wargs[0], XmNsubMenuId, submenu_file);
- XtSetValues(file_menu, wargs, 1);
-
- boxes[4] = XtCreateManagedWidget("view",xmPushButtonWidgetClass,
- submenu_file, NULL,0);
- XtAddCallback(boxes[4], XmNactivateCallback,view, NULL);
- boxes[5] = XtCreateManagedWidget("topview",
- xmPushButtonWidgetClass, submenu_file, NULL,0);
- XtAddCallback(boxes[5], XmNactivateCallback,view, NULL);
- boxes[6] = XtCreateManagedWidget("edit",
- xmPushButtonWidgetClass, submenu_file, NULL,0);
- XtAddCallback(boxes[6], XmNactivateCallback,do_menu, NULL);
- boxes[7] = XtCreateManagedWidget("print",
- xmPushButtonWidgetClass, submenu_file, NULL,0);
- XtAddCallback(boxes[7], XmNactivateCallback,do_menu, NULL);
-
- /* if it a directory */
- submenu_dir = XmCreatePulldownMenu(menu, "dirsubmenu", NULL, 0);
- XtSetArg(wargs[0], XmNsubMenuId, submenu_dir);
- XtSetValues(dir_menu, wargs, 1);
- boxes[8] = XtCreateManagedWidget("show subtree",
- xmPushButtonWidgetClass, submenu_dir, NULL,0);
- XtAddCallback(boxes[8], XmNactivateCallback,do_menu, NULL);
- boxes[9] = XtCreateManagedWidget("list files",
- xmPushButtonWidgetClass, submenu_dir, NULL,0);
- XtAddCallback(boxes[9], XmNactivateCallback,do_menu, NULL);
- boxes[10] = XtCreateManagedWidget("list ../",
- xmPushButtonWidgetClass, submenu_dir, NULL,0);
- XtAddCallback(boxes[10], XmNactivateCallback,do_menu, NULL);
- }
- /* Not used here, but may be useful in the future !!! */
- /* Copied from D. Young's book */
- /*
- void post_menu_handler(w, menu, event)
- Widget w, menu;
- XEvent *event;
- {
- Arg wargs[10];
- int button;
-
- XtSetArg(wargs[0], XmNwhichButton, &button);
- XtGetValues(menu, wargs, 1);
- if(event->xbutton.button == button) {
- XmMenuPosition(menu, event);
- XtManageChild(menu);
- }
- }
- */
- /* Quick and dirty way to view a file in a pop-up window
- Speed may improve, if one reads and displays page by page
- No check to see if the file is binary
- */
- void view(w, call_mydata, call_data)
- Widget w;
- caddr_t call_data, call_mydata;
-
- {
- struct entry *branch;
- char *filename[MAXPATHLEN+1];
- struct stat statbuf; /* Information on a file. */
- int file_length; /* Length of file. */
- unsigned char * file_string; /* Contents of file. */
- FILE *fp = NULL;
- Widget text, toplevel2, sw2, button, frame, main_w, menu_bar;
- Widget title;
- XmString name_string = NULL;
- char *button_name = NULL;
- int topflag=0;
- Arg wargs[10];
- int n=0;
-
- branch = file_pointer;
- /* find which button called us */
- XtSetArg(wargs[0], XmNlabelString, &name_string);
- XtGetValues(w,wargs,1);
- XmStringGetLtoR(name_string,XmSTRING_DEFAULT_CHARSET,&button_name);
- if(strcmp("topview",button_name) == 0) topflag = 1;
-
- /* find first the correct path */
-
- strncpy(filename,branch->path_name,MAXPATHLEN);
- strcat(filename,"/");
- strcat(filename,branch->e_name);
-
-
- if ((fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr,"Can't open file name %s\n",filename);
- return;
- }
- if (stat(filename, &statbuf) == 0)
- file_length = statbuf.st_size;
- else
- file_length = 1000000; /* arbitrary file length */
-
- /* read the file string */
-
- if(topflag == 1 && file_length >= 2000 ) file_length = 2000;
-
- file_string = (unsigned char *) XtMalloc((unsigned)file_length);
- fread(file_string, sizeof(char), file_length, fp);
-
- if (fclose(fp) != NULL) fprintf(stderr, "Warning: unable to close file.\n");
-
- /* Create another pop-pup top-shell with a MainWindow */
-
- toplevel2 = XtCreateApplicationShell("Dtreef",topLevelShellWidgetClass,
- NULL,0);
-
- main_w = XmCreateMainWindow(toplevel2,"mainw",NULL,0);
- XtManageChild(main_w);
- menu_bar = XmCreateMenuBar(main_w,"menu",NULL,0);
- XtManageChild(menu_bar);
- XtSetArg(wargs[0], XmNshadowType, XmSHADOW_OUT);
- frame = XmCreateFrame(main_w,"frame",wargs,1);
- XtManageChild(frame);
- XtSetArg(wargs[0], XmNscrollingPolicy, XmAUTOMATIC);
- sw2 = XtCreateManagedWidget("swindowf",
- xmScrolledWindowWidgetClass,frame, wargs,1);
- XmMainWindowSetAreas(main_w, menu_bar, NULL, NULL, NULL, frame);
- button = XmCreateCascadeButton(menu_bar, "quit",NULL,0);
- XtManageChild(button);
- XtAddCallback(button,XmNactivateCallback,quit_b_pop,toplevel2);
-
- title = XtCreateManagedWidget("title",
- xmCascadeButtonWidgetClass, menu_bar, NULL,0);
- w_print(title, filename);
-
-
- /* Create Text widget */
- n=0;
- XtSetArg (wargs[n], XmNeditable, FALSE); n++;
-
- text = XmCreateText(sw2, "text", wargs, n);
-
- /* added the file string to the text widget */
-
- XmTextSetString(text, file_string);
- if(file_string != NULL) XtFree(file_string);
- if(name_string != NULL) XtFree(name_string);
-
- /* Poput the text file */
-
- XtPopup(toplevel2,XtGrabNone);
- XtManageChild(text);
- }
-
- /* CallBack function of the quit button on a pop-up window */
-
- void quit_b_pop(w, topshell, call_data)
- Widget w;
- Widget topshell;
- caddr_t call_data;
- {
- XtPopdown(topshell);
- }
-
- /* function that forks a command from the menu */
- /* Needs work!!!!!
- */
- void do_menu(w,call_mydata,call_data)
- Widget w;
- caddr_t call_data, call_mydata;
-
- {
- struct entry *branch;
- char *filename[MAXPATHLEN+1];
- char *topdir[MAXPATHLEN+1];
- XmString name_string = NULL;
- char *button_name = NULL;
- char *lpdest=NULL, *editor = NULL;
- char *EDITOR="EDITOR\0";
- int pid, pathl,namel;
- Arg wargs[3];
-
-
-
- /* find which button called us */
-
- branch = file_pointer;
- XtSetArg(wargs[0], XmNlabelString, &name_string);
- XtGetValues(w,wargs,1);
- XmStringGetLtoR(name_string,XmSTRING_DEFAULT_CHARSET,&button_name);
-
-
- /* find first the correct path - append the file name
- except for the "root" directory */
-
- strncpy(filename,branch->path_name,MAXPATHLEN);
- if(branch->next != 1) {
- strcat(filename,"/");
- strcat(filename,branch->e_name);
- }
-
- /* fork a new process */
- pid = fork();
-
- if(pid > 0) {
- /* wait((int *)0); */
- return;
- }
-
- if(pid == 0) {
- /* for(fd = 0; fd < _NFILE; fd++) close(fd); */
- if(strcmp(button_name,"print") == 0) {
-
- lpdest = XGetDefault(XtDisplay(w),"dtree","lpdest");
- if (lpdest != NULL){
- execl("/usr/bin/lp","lp","-d",lpdest,filename,(char *)0);
- }
- else
- execl("/usr/bin/lp","lp",filename,(char *)0);
- }
- else if(strcmp(button_name,"edit") == 0) {
-
- editor = XGetDefault(XtDisplay(w),"dtree","editor");
-
- if (editor == NULL) {
- editor = getenv(EDITOR);
- if(editor == NULL)
- editor="/usr/bin/vi";
- execl("/usr/bin/X11/hpterm",
- "hpterm","-e",editor,
- filename,(char *)0);
- } else
- execlp(editor,editor, filename,(char *)0);
- }
- else if(strcmp(button_name,"list files") == 0) {
- execlp("dtree", "dtree",
- "-a", "-l","1",filename, (char *)0);
- }
- else if(strcmp(button_name,"list ../") == 0) {
-
- /* find the parent directory */
- pathl = strlen(filename);
- namel = strlen(branch->e_name);
- strncpy(topdir,branch->path_name,pathl-namel);
-
- execlp("dtree", "dtree", "-l","1",topdir, (char *)0);
- }
-
- else
- execlp("dtree", "dtree",
- "-a",filename, (char *)0);
-
- fprintf(stderr,"%s command failed\n",button_name);
- }
- fprintf(stderr,"fork for %s command failed\n",button_name);
- }
-
- /* Function that updates the pop-up menu labels and permissions
- when someone clicks on a node.
- */
- void clickB( w,branch,call_data)
- Widget w;
- struct entry *branch;
- caddr_t call_data;
- {
- Arg wargs[3];
- XrmValue bgcolor;
- if(branch->dir == 1) {
- XtSetSensitive(file_menu ,FALSE);
- XtSetSensitive(dir_menu ,True);
- }
- else {
- XtSetSensitive(dir_menu ,False);
- #ifdef STATS
- /* Don't do anything with symb. links */
- if(strncmp(" l",getmode(branch->e_mode),2) == 0)
- XtSetSensitive(file_menu ,False);
- else
- #endif /* STATS */
- XtSetSensitive(file_menu ,True);
- }
- w_print(options, branch->e_name);
-
- /* Get the background color of the activated button
- Need to get the foreground color too
- */
- _XmSelectColorDefault (w, NULL, &bgcolor);
- XtSetArg(wargs[0], XmNbackground, *((Pixel *) bgcolor.addr));
- XtSetValues(options, wargs, 1);
- file_pointer = branch;
- button_print(branch);
- }
-
- /* Print a string on a widget */
-
- void w_print(w, string)
- Widget w;
- char *string;
- {
- XmString xmstr;
- Arg wargs[2];
-
- xmstr = XmStringLtoRCreate(string, XmSTRING_DEFAULT_CHARSET);
- XtSetArg(wargs[0], XmNlabelString, xmstr);
- XtSetValues(w,wargs, 1);
- }
-
- /* print the labels on the popup menu */
- void button_print(branch)
- struct entry *branch;
- {
- char tmp[40];
- /* w_print(boxes[0], branch->e_name); */
- #ifdef STATS
- strncpy(tmp,"Mode :",40);
- strcat(tmp,getmode(branch->e_mode));
- w_print(boxes[1],tmp);
- strncpy(tmp,"User :",40);
- strcat(tmp,guid(branch->e_uid));
- w_print(boxes[2], tmp);
- strncpy(tmp,"Group:",40);
- strcat(tmp, ggid(branch->e_gid));
- w_print(boxes[3], tmp);
- #endif /* STATS */
- }
-
- /*
- * Copied from D. Young's book with some changes
- * Define three callbacks. Make them static - no need
- * to make them known outside this file.
- */
- static void arm_callback(w, flag, call_data)
- Widget w;
- int *flag;
- XmAnyCallbackStruct *call_data;
- {
- *flag = FALSE;
- }
- static void activate_callback(w, flag, call_data)
- Widget w;
- int *flag;
- XmAnyCallbackStruct *call_data;
- {
- *flag = TRUE;
- }
- static void disarm_callback(w, flag, call_data)
- Widget w;
- int *flag;
- XmAnyCallbackStruct *call_data;
- {
- if(*flag){
- XtCloseDisplay(XtDisplay(w));
- exit(0);
- }
- }
-
- /* function to re-orient the graph */
- #ifndef TREE
- void re_orient(w, graph, call_data)
- Widget w, graph;
- caddr_t call_data;
-
- {
- Arg wargs[2];
- XtSetArg(wargs[0], XmNreorient, True);
- XtSetValues(graph, wargs, 1);
- }
- #endif
- @EOF
-
- chmod 444 dtree.c
-
- echo x - Makefile
- cat >Makefile <<'@EOF'
- # Makefile for dtree
-
- # Things that might go in DEFS:
- # -DSTATS -DNEWDIR -DDIRENT -DNDIR -DSYSV
- # The -DTREE flag is used to create dtree with the Tree widget
- # otherwise it uses the XmGraph widget.
- DEFS = -D_HPUX_SOURCE -DSTATS -DNEWDIR -DSYSV #-DDIRENT -DS_IFLNK
- CFLAGS = $(DEFS) -O
- LDFLAGS =
- LIBS = # For Xenix use -lx with -DNDIR
- LIBS = -lmalloc -lXm -lXt -lX11 -lm
-
-
- BINDIR = /usr/local/bin/X11
- MANDIR = /usr/local/man/man1
-
- OBJECTS_A = dtree.o Arc.o Graph.o #using XmGraph
- OBJECTS_B = dtree_tree.o Tree.o #using D. Young's tree.
-
- ARCH_FILES = dtree.1 dtree.c Makefile Dtree Tree.h TreeP.h \
- dtree-i.h Tree.c Arc.c Arc.h ArcP.h Graph.c Graph.h GraphP.h
-
- ARCH_FILESB = dtree.1 dtree.c Makefile Dtree dtree-i.h Imakefile README
-
-
- all: dtree_tree
-
- dtree: $(OBJECTS_A)
- $(CC) -o dtree $(LDFLAGS) $(OBJECTS_A) $(LIBS)
-
- dtree_tree: $(OBJECTS_B)
- $(CC) -o dtree $(LDFLAGS) $(OBJECTS_B) $(LIBS)
-
- Arc.o: Arc.c
- $(CC) -c $(CFLAGS) Arc.c +Ns4000
-
- Graph.o: Graph.c
- $(CC) -c $(CFLAGS) Graph.c +Ns4000
-
- dtree_tree.o: dtree.c
- $(CC) -o dtree_tree.o -c $(CFLAGS) -DTREE dtree.c
-
- install: dtree dtree.1
- cp dtree $(BINDIR)
- cp dtree.1 $(MANDIR)
-
- lint: dtree.c
- lint $(DEFS) dtree.c
-
- shar: $(ARCH_FILESB)
- shar $(ARCH_FILESB) > dtree.shar_1
- shar Tree* > dtree.shar_2
- dist: dtree.tar.Z
-
- tar: dtree.tar.Z
-
- dtree.tar.Z: $(ARCH_FILES)
- tar cf - $(ARCH_FILES) | compress > dtree.tar.Z
-
- clean:
- rm -f dtree *.o core tags a.out
- @EOF
-
- chmod 644 Makefile
-
- echo x - Dtree
- cat >Dtree <<'@EOF'
- #
- # app-defaults file for dtree
- #
- dtree*geometry: 500x500
- dtree*dir.background: Red
- dtree*file.background: Gray
- dtree*sym_link.background: Brown
- dtree*quit.background: DarkSlateBlue
- dtree*options.background: Red
- dtree*XmGraph*childSpacing: 50 #distance between levels
- Mwm*Dtree*iconImage: /usr/local/include/X11/bitmaps/dtree-i.h
- Hpwm*Dtree*iconImage: /usr/local/include/X11/bitmaps/dtree-i.h
- !dtree*lpdest: rljet #Printer destination
- !dtree*editor: emacsclient #window-clever editor
- !dtree*sym_link.foreground:
- @EOF
-
- chmod 644 Dtree
-
- echo x - dtree-i.h
- cat >dtree-i.h <<'@EOF'
- #define load_i_width 50
- #define load_i_height 50
- static char load_i_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
- 0x00, 0xf8, 0x0f, 0x10, 0x00, 0x20, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x20, 0x00, 0x00, 0x0f, 0x08,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x09, 0x08, 0x10, 0x00, 0x20, 0x00, 0x80,
- 0x08, 0x08, 0x00, 0x00, 0x20, 0x00, 0x80, 0xf8, 0x0f, 0x10, 0x00, 0x20,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0xfe,
- 0x13, 0xfe, 0xe3, 0x17, 0x00, 0x20, 0x02, 0x0a, 0x02, 0x22, 0x04, 0x00,
- 0x20, 0xaa, 0x0a, 0x56, 0x23, 0x14, 0x00, 0x20, 0x02, 0xfe, 0x03, 0x3e,
- 0x04, 0x00, 0x20, 0xaa, 0x0a, 0xaa, 0x22, 0x14, 0x00, 0x20, 0x02, 0x0a,
- 0x02, 0x22, 0x04, 0x00, 0x20, 0xfe, 0x13, 0xfe, 0xe3, 0x17, 0x00, 0x20,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0xf8,
- 0x0f, 0x10, 0x00, 0x20, 0x00, 0x40, 0x08, 0x08, 0x00, 0x00, 0x20, 0x00,
- 0x80, 0x08, 0x08, 0x10, 0x00, 0x20, 0x00, 0x80, 0x08, 0x08, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x0f, 0x08, 0x10, 0x00, 0x20, 0x00, 0x00, 0x08, 0x08,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0xf8, 0x0f, 0x10, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x55, 0x55, 0x55,
- 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00};
- @EOF
-
- chmod 644 dtree-i.h
-
- echo x - Imakefile
- cat >Imakefile <<'@EOF'
- #Imakefile to create dtree using the "tree" widget.
-
- DEFINES = -DSTATS -DNEWDIR -DSYSV -DTREE
- LOCAL_LIBRARIES =
- SYS_LIBRARIES = -lmalloc -lXm -lXt -lX11 -lm
- SRCS = dtree.c Tree.c
- OBJS = dtree.o Tree.o
-
- ComplexProgramTarget(dtree)
-
-
- @EOF
-
- chmod 644 Imakefile
-
- echo x - README
- cat >README <<'@EOF'
- This version of dtree is an X extension of the program originally
- written by Dave Borman. It displays on a terminal or under X11
- (using Motif widgets) the tree structure of a Unix directory tree.
- On a color terminal, different colors can be used for files, directories,
- and symbolic links. One can select nodes of the tree, and edit them,
- view them, or print them. One can also traverse nodes not fully
- shown on the original tree.
-
- The program uses the "tree" widget described in D. Young's book on
- X window programming (code included here). The program also runs
- using the XmGraph widget, but because that code is not yet stable,
- the code for the XmGraph widget is not included here.
- To make the program run: make dtree_tree
-
- The program runs faster with the "tree" widget, but the XmGraph
- widgets may provide the potential for additional capabilities, such
- as: removing files from the tree, copying of files and directories, etc.
-
- Potential problem: because dtree creates a PushButton widget for every file
- or directory shown, you may run out of memory. It is recommended that you
- start with a moderate size tree, and create new ones as needed.
- Experience will show how much you can push it!!
- If you have a monochrome monitor, you may want to substitute those
- widgets with gadgets.
-
- For example: dtree -l 2
- will show the tree of your current directory up to depth 2.
- dtree -al 2
- will show both files and directories up to depth 2.
-
- K. Konstantinides
- HP Labs
- kk@hpkronos.hpl.hp.com
- @EOF
-
- chmod 644 README
-
- exit 0
-
- dan
- ----------------------------------------------------
- O'Reilly && Associates argv@sun.com / argv@ora.com
- Opinions expressed reflect those of the author only.
-